package com.gitee.feizns.web.boot.rest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 常用的restTemplate工具类
 * @author feizns
 * @since 2019/7/15
 */
@Configuration
@Order
public class RestTemplateAutoConfiguration {

    private static final Logger LOGGER = LoggerFactory.getLogger(RestTemplateAutoConfiguration.class);

    @ConditionalOnMissingBean
    @Bean
    public RestTemplate restTemplate(HttpMessageConverter[] messageConverters) {

        RestTemplate restTemplate = new RestTemplate();

        restTemplate.setErrorHandler(new ResponseErrorHandler() {
            @Override
            public boolean hasError(ClientHttpResponse response) throws IOException {
                return !response.getStatusCode().is2xxSuccessful();
            }

            @Override
            public void handleError(ClientHttpResponse response) throws IOException {
                if ( LOGGER.isDebugEnabled() ) {
                    LOGGER.debug("REST_REQUEST_FAIL: STATUS  [ %s ] STATUS_TEXT [ %s ].", response.getStatusCode(), response.getStatusText());
                    LOGGER.debug("REST_REQUEST_FAIL: HEADERS [ %s ].", response.getHeaders());
                    LOGGER.debug("REST_REQUEST_FAIL: BODY    [ %s ].", response.getBody());
                }
                throw new ThirdRequestFailException(response.getStatusCode() + " : " + response.getStatusText());
            }

        });

        List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
        restTemplate.setMessageConverters(converters(converters.stream().toArray(HttpMessageConverter[]::new)));
        return restTemplate;
    }

    private List<HttpMessageConverter<?>> converters(HttpMessageConverter<?>... converters) {
        List<HttpMessageConverter<?>> ret = new ArrayList<>();
        ret.add(new CustomizeMappingJackson2HttpMessageConverter());
        ret.addAll(Arrays.asList(converters));
        return ret;
    }

    private static class CustomizeMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
        public CustomizeMappingJackson2HttpMessageConverter() {
            setSupportedMediaTypes(Arrays.asList(MediaType.ALL));
        }
    }

    /**
     * 第三方调用异常
     */
    public static final class ThirdRequestFailException extends RuntimeException {

        public ThirdRequestFailException(String message) {
            super(message);
        }

    }

}
